<template>
  <div class="rcdg-condition-filter">
    <div v-if="title" class="tags-box">
      <div class="tag-title">{{ title }}</div>
      <template v-for="(tag, key) in selectedTags">
        <el-tag :key="key" v-if="showTags && tag.children.length" closable effect="plain" @close="removeTag(key)">
          {{ tag.label }}:
          <template v-for="(li, i) in tag.children">
            {{ li.label }}
            <template v-if="i < tag.children.length - 1">,</template>
          </template>
        </el-tag>
      </template>
      <div class="coll">
        <i class="switch-arrow" :class="isFold ? 'el-icon-arrow-down' : 'el-icon-arrow-up'" @click="isFold = !isFold">
          {{ isFold ? '展开' : '收起' }}
        </i>
      </div>
    </div>
    <div class="conditions-box" v-show="!isFold">
      <div class="filter">
        <div class="filter-warp" v-if="conditionList.length">
          <div class="filter-flex" v-for="item in conditionList" :key="item.value">
            <span class="filter-title">{{ item.label }}</span>
            <template v-if="item.children.length">
              <div class="filter-content">
                <div :id="item.value" class="filter-tab" :class="{ 'filter-show': subUnfolds.includes(item.value) }">
                  <span
                    class="tag-item"
                    :class="{
                      'filter-active': selectedTags[item.value].children.length === 0,
                      disabled: disabled,
                    }"
                    @click="handlerItemClick(item.value)">
                    全部
                  </span>
                  <span
                    v-for="tag in item.children"
                    :key="tag.value"
                    class="tag-item"
                    :class="{
                      'filter-active': !tag.disabled && tag.selected,
                      disabled: disabled || tag.disabled,
                    }"
                    @click="handlerItemClick(item.value, tag)">
                    {{ tag.label }}
                  </span>
                </div>
              </div>
              <div class="filter-more" @click="toggleSubTags(item.value)" v-if="wrapData[item.value]">
                <i
                  class="switch-arrow"
                  :class="subUnfolds.includes(item.value) ? 'el-icon-arrow-up' : 'el-icon-arrow-down'">
                  {{ subUnfolds.includes(item.value) ? '收起' : '展开' }}
                </i>
              </div>
            </template>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { debounce } from '@utility/utility'

export default {
  name: 'ConditionFilter',
  model: {
    prop: 'value',
    event: 'valueChange',
  },
  props: {
    value: {
      type: Object,
      default: () => {},
    },
    source: {
      type: [Object, Array],
    },
    options: {
      type: Object,
      default: () => ({ label: 'label', value: 'value', children: 'children' }),
    },
    // 条件筛选的标题
    title: {
      type: String,
      default: '所选条件：',
    },
    // 每个筛选条件是否多选
    isMulti: {
      type: Boolean,
      default: true,
    },
    // 所有筛选条件不可选
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否展示已选的条件
    showTags: {
      type: Boolean,
      default: true,
    },
    // 是否折叠
    fold: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      conditions: {},
      selectedTags: {},
      isFold: this.fold, // 是否折叠筛选条件
      subUnfolds: [], // 筛选条件中的折叠按钮是否打开
      wrapData: {}, // 是否展示折叠按钮
    }
  },
  computed: {
    conditionList() {
      const list = []
      for (const i in this.conditions) {
        list.push(this.conditions[i])
      }
      return list
    },
  },
  watch: {
    value: {
      deep: true,
      handler(obj) {
        if (Object.keys(obj).length === 0 && Object.keys(this.selectedTags).length !== 0) {
          this.initSelectedTags()
          this.onSelectedChange(null)
        } else {
          // check select status
          console.log('%c⧭', 'color: #731d1d', obj, this.selectedTags)
        }
      },
    },
    // value: {
    //   handler(obj) {
    //     if (Object.keys(obj).length === 0 && Object.keys(this.selectedTags).length !== 0) {
    //       this.initSelectedTags()
    //       this.onSelectedChange(null)
    //     }
    //   },
    // },
    source: {
      handler(data) {
        if (data && typeof data === 'object') {
          const conditons = {}
          if (Array.isArray(data)) {
            data.forEach(item => {
              const uniqueKey = item[this.options.value]
              const filters = (item[this.options.children] || []).map(con => {
                return {
                  label: con[this.options.label],
                  value: con[this.options.value],
                  selected: false,
                  disabled: !!con.disabled,
                }
              })
              this.selectedTags[uniqueKey] = { label: item[this.options.label], children: [] }
              this.wrapData[uniqueKey] = false
              conditons[uniqueKey] = {
                label: item[this.options.label],
                value: uniqueKey,
                children: filters,
              }
            })
          } else {
            for (const i in data) {
              this.selectedTags[i] = { label: data[i][this.options.label], children: [] }
              this.wrapData[i] = false
              const filters = (data[i][this.options.children] || []).map(con => {
                return {
                  label: con[this.options.label],
                  value: con[this.options.value],
                  selected: false,
                  disabled: !!con.disabled,
                }
              })
              conditons[i] = {
                label: data[i][this.options.label],
                value: i,
                children: filters,
              }
            }
          }
          this.conditions = conditons
          this.initSelectedTags()
          // this.onSelectedChange(null)
        }
      },
      immediate: false,
      deep: true,
    },
    fold(bool) {
      this.isFold = bool
    },
    isFold(val) {
      if (!val) {
        this.$nextTick(() => {
          this.checkRowWrap()
        })
      }
    },
  },
  mounted() {
    this.checkRowWrap = debounce(this.checkRowWrapData, 300)
    window.addEventListener('resize', this.checkRowWrap)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.checkRowWrap)
  },
  methods: {
    initSelectedTags() {
      if (typeof this.value === 'object' && Object.keys(this.value).length) {
        for (const key in this.value) {
          const itemVal = this.value[key]
          if (Array.isArray(itemVal) && itemVal.length) {
            this.isFold = false
            const conItem = JSON.parse(JSON.stringify(this.conditions[key]))
            if (conItem && conItem.children) {
              this.$set(this.selectedTags, key, {
                label: conItem.label,
                children: conItem.children.filter(fItem => itemVal.includes(fItem.value)),
              })
              conItem.children.forEach(item => {
                item.selected = itemVal.includes(item.value)
              })
              this.conditions[key] = conItem
            }
          }
        }
      } else {
        for (const key in this.conditions) {
          const conItem = JSON.parse(JSON.stringify(this.conditions[key]))
          if (conItem && conItem.children) {
            this.$set(this.selectedTags, key, {
              label: conItem.label,
              children: [],
            })
            conItem.children.forEach(item => {
              item.selected = false
            })
            this.conditions[key] = conItem
          }
        }
      }
    },
    // 检测筛选条件是否折行
    checkRowWrapData() {
      if (this.conditions) {
        const wrapData = {}
        for (const key in this.conditions) {
          const filterEls = this.$el.querySelectorAll(`#${key}>span`)
          let isWrap = false
          if (filterEls.length) {
            const firstEl = filterEls[0]
            const lastEl = filterEls[filterEls.length - 1]
            isWrap = firstEl.offsetTop !== lastEl.offsetTop
          }
          wrapData[key] = isWrap
        }
        this.wrapData = wrapData
      }
    },
    toggleSubTags(subKey) {
      const subIdx = this.subUnfolds.findIndex(item => {
        return item === subKey
      })
      if (subIdx === -1) {
        this.subUnfolds.push(subKey)
      } else {
        this.subUnfolds.splice(subIdx, 1)
      }
    },
    handlerItemClick(key, tag) {
      if (this.disabled || (tag && tag.disabled)) return false
      let selectedList = JSON.parse(JSON.stringify(this.selectedTags[key].children))
      // 点击全部
      if (!tag) {
        if (selectedList.length) {
          this.$set(this.selectedTags, key, { label: this.selectedTags[key].label, children: [] })
          this.conditions[key].children.forEach(item => {
            item.selected = false
          })
        } else {
          return false
        }
      } else {
        const curInx = selectedList.findIndex(item => item.value === tag.value)
        if (curInx > -1) {
          selectedList.splice(curInx, 1)
          if (selectedList.length === 0) {
            this.conditions[key].children.forEach(item => {
              item.selected = false
            })
          } else {
            this.conditions[key].children.forEach(item => {
              item.selected = item.value === tag.value ? false : item.selected
            })
          }
          this.$set(this.selectedTags, key, { label: this.selectedTags[key].label, children: selectedList })
        } else {
          if (this.isMulti) {
            if (selectedList.length === this.conditions[key].children.length - 1) {
              selectedList = []
              this.conditions[key].children.forEach(item => {
                item.selected = false
              })
            } else {
              selectedList.push(tag)
              this.conditions[key].children.forEach(item => {
                item.selected = item.value === tag.value ? true : item.selected
              })
            }
          } else {
            selectedList = [{ ...tag }]
            this.conditions[key].children.forEach(item => {
              item.selected = item.value === tag.value
            })
          }
          this.$set(this.selectedTags, key, { label: this.selectedTags[key].label, children: selectedList })
        }
      }
      this.onSelectedChange(key)
    },
    removeTag(key) {
      this.$set(this.selectedTags, key, { ...this.selectedTags[key], children: [] })
      this.conditions[key].children.forEach(item => {
        item.selected = false
      })
      this.onSelectedChange(key)
    },
    onSelectedChange(rowKey) {
      const selResult = {}
      // 重新赋值
      for (const key in this.selectedTags) {
        selResult[key] = this.selectedTags[key].children.map(item => {
          return item.value
        })
      }
      this.$emit('valueChange', selResult)
      this.$emit('change', selResult, rowKey)
    },
  },
}
</script>
<style lang="scss" scoped>
.rcdg-condition-filter {
  .tags-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    position: relative;
    padding-right: 80px;
    margin-bottom: 10px;
    .tag-title {
      font-size: 16px;
      color: #333333;
      text-align: right;
      font-weight: bold;
    }
    .el-tag {
      height: 20px;
      line-height: 20px;
      margin-left: 4px;
      border: 1px dashed #3b93f7;
      border-radius: 2px;
      box-sizing: content-box;
      font-size: 14px;
    }
    .coll {
      position: absolute;
      top: 0;
      right: 20px;
      text-align: left;
      color: #666666;
      font-size: 16px;
      cursor: pointer;
    }
  }
  .conditions-box {
    max-height: 300px;
    overflow: auto;
    background-color: #f3f8ff;
    section {
      display: flex;
      flex-direction: column;
    }
    /* 过滤列表:start */
    .filter {
      width: 100%;
    }
    .filter-warp {
      display: flex;
      margin: auto;
      height: 100%;
      flex-direction: column;
      padding: 10px 15px;
    }

    .filter-flex {
      display: flex;
      margin-bottom: 10px;
      position: relative;
    }

    .filter-flex:last-of-type {
      margin-bottom: 0;
    }
    .filter-title {
      flex-basis: 70px;
      margin-top: 5px;
      font-size: 14px;
    }
    .filter-content {
      display: flex;
      flex: 1;
    }
    .filter-tab {
      flex: 1;
      padding-right: 48px;
      height: 35px;
      overflow: hidden;
      font-size: 14px;
    }
    .tag-item {
      display: inline-block;
      margin: 0 5px 6px 5px;
      cursor: pointer;
      padding: 5px 10px;
      color: #666666;
      font-size: 14px;
      &:not(.disabled):hover {
        background-color: #3b93f7;
        color: white;
        border-radius: 3px;
      }
    }
    .filter-more {
      position: absolute;
      right: 0;
      top: 5px;
      cursor: pointer;
      color: #666;
      font-size: 14px;
    }
    .filter-active {
      background-color: #3b93f7;
      color: white !important;
      border-radius: 3px;
    }
    .disabled {
      cursor: not-allowed;
      color: #999;
    }
    .filter-show {
      min-height: 35px;
      height: auto !important;
    }
  }
}
</style>
